<!DOCTYPE HTML>
<html>
<head>
    <!-- twitter bootstrap CSS stylesheet - included to make things pretty, not needed or used by cornerstone -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <h1>
        Composite Images
    </h1>

    This example shows you how to add and interact with layers.
    <div class="row">
        <div class="col-xs-2">
            <label>Viewport Values:</label>
            <div><span>Viewport Scale: </span><span id="layerViewportScale"></span></div>
        </div>
        <div class="col-xs-4">
            <label>Layer CT Values:</label>
            <div><span>Viewport Scale: </span><span id="layer1ViewportScale"></span></div>
            <div><span>Layer Viewport Scale: </span><span id="layer1LayerViewportScale"></span></div>
            <div><span>Layer Sync Scale: </span><span id="layer1LayerSyncScale"></span></div>
        </div>
        <div class="col-xs-4">
            <label>Layer PET Values:</label>
            <div><span>Layer Viewport Scale: </span><span id="layer2LayerViewportScale"></span></div>
            <div><span>Layer Sync Scale: </span><span id="layer2LayerSyncScale"></span></div>
        </div>
    </div>
    <div class="row" style="padding-top: 20px;">
        <div class="col-xs-10">
            <div id="dicomImage"
                 style="width:512px;height:512px;top:0px;left:0px;position:absolute"
                 oncontextmenu="return false"
                 onmousedown="return false">
            </div>
        </div>
        <div class="col-xs-2">
            <div style="margin-bottom: 15px;">
                <label for="syncViewports"> Sync Viewports
                    <input id="syncViewports" name="syncViewports" type="checkbox" checked/>
                </label>
                <br>
            </div>

            <label for="layers">Select active layer</label>
            <select name="layers" id="layers" size="2" style="width: 100%; min-width: 150px;"></select>
            <div id="properties" style="width: 100%; min-width: 150px; margin-top: 15px;">
                <label>Layer Properties</label>
                <div style="width: 100%; padding: 5px 5px 5px 10px;">
                    <div style="margin-bottom: 15px;">
                        <label for="visible"> Visible
                            <input name="visible" type="checkbox" checked/>
                        </label>
                        <br>
                    </div>
                    <div style="margin-bottom: 15px;">
                        <label for="colormaps"> Colormap </label>
                        <select id="colormaps" style="width:100%">
                            <option value="">None</option>
                        </select>
                    </div>
                    <div style="margin-bottom: 15px;">
                        <label for="imageOpacity"> Opacity</label>
                        <input id="imageOpacity" type="range" class="range" min=0 max=1 step=0.1 value=0>
                    </div>
                </div>
            </div>
        </div>
        <!-- <div class="col-xs-12">
        </div> -->
    </div>
</div>
</body>

<!-- include the cornerstone library -->
<script src="../../dist/cornerstone.js"></script>
<script>window.cornerstone || document.write('<script src="https://unpkg.com/cornerstone-core">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../petctImageIdLoader.js"></script>
<script src="../petctMetaDataProvider.js"></script>

<script>
    // Enable the dicomImage element
    const element = document.getElementById('dicomImage');
    cornerstone.enable(element);

    // JSON with all layers to be loaded
    // The `name` option is used only by this example and
    // cornerstone doesn't even know that it exists.
    // You can add any option you want to `options` object.
    const layers = [{
            imageId: 'ct://1',
            options: {
                name: 'CT'
            }
        }, {
            imageId: 'pet://1',
            options: {
                name: 'PET',
                opacity: 0.7,
                viewport: {
                    colormap: 'hotIron',
                    voi: {
                        windowWidth: 30,
                        windowCenter: 16
                    }
                }
            }
        }
    ];

    // This is the main function responsible for loading all layers
    // This method will wait for all images to be loaded (`loadImages`)
    // before adding the layers
    function loadLayers() {
        loadImages().then(function(images) {
            images.forEach(function(image, index) {
                const layer = layers[index];
                const layerId = cornerstone.addLayer(element, image, layer.options);

                cornerstone.updateImage(element);
                console.log('Layer ' + index + ': ' + layerId);
            });

            // Update dropdown size to make all layers name visible
            const layersDropdown = document.getElementById('layers');
            layersDropdown.size = layers.length;

            // Listen to `change` event to set the selected layer as active
            layersDropdown.addEventListener('change', function(event) {
                const layerId = event.currentTarget.value;
                cornerstone.setActiveLayer(element, layerId);
            });
        });
    }

    // This method loads the image of each layer and resolve the
    // promise only after getting all of them loaded
    function loadImages() {
        const promises = [];

        layers.forEach(function(layer) {
            const loadPromise = cornerstone.loadAndCacheImage(layer.imageId);
            promises.push(loadPromise);
        });

        return Promise.all(promises);
    }

    // Select the right layer in the dropdown
    function updateSelectedLayer(layerId) {
        const layers = document.getElementById('layers');
        const currentLayerId = layers.value;

        if(currentLayerId !== layerId) {
            layers.value = layerId;

            // Trigger a change event
            const event = new Event('change');
            element.dispatchEvent(event);
        }
    }

    // Listen to `change` event to activate/deactivate the viewport synchronization
    document.querySelector('input[name=syncViewports]').addEventListener('change', function(event) {
        const enabledElement = cornerstone.getEnabledElement(element);
        enabledElement.syncViewports = event.currentTarget.checked;
        cornerstone.updateImage(element);
    });

    document.getElementById('colormaps').addEventListener('change', function() {
        const layer = cornerstone.getActiveLayer(element);
        layer.viewport.colormap = document.getElementById('colormaps').value;
        cornerstone.updateImage(element);
    });

    // Listen to `change` event to update the opacity of the active layer
    document.getElementById("imageOpacity").addEventListener('change', function(event) {
        const layer = cornerstone.getActiveLayer(element);
        layer.options.opacity = parseFloat(event.currentTarget.value);
        cornerstone.updateImage(element);
    });

    // Listen to `change` event to update the visibility of the active layer
    document.querySelector('input[name=visible]').addEventListener('change', function(event) {
        const layer = cornerstone.getActiveLayer(element);
        layer.options.visible = event.currentTarget.checked;
        cornerstone.updateImage(element);
    });

    // This event will be called every time a layer is added through cornerstone.addLayer
    // The layer is added to the dropdown to make it possible to select and interact with it
    element.addEventListener('cornerstonelayeradded', function(e) {
        const eventData = e.detail;
        const layer = cornerstone.getLayer(eventData.element, eventData.layerId);
        const layers = document.getElementById('layers');

        const layerOption = document.createElement("OPTION");
        layerOption.value = layer.layerId;
        layerOption.textContent = layer.options.name;

        // Set the layer as selected in case its the the first layer to be added
        if(layers.childElementCount === 0) {
            layerOption.checked = true;
        }

        layers.appendChild(layerOption);
    });

    // This event will be called every time cornerstone.setActiveLayer is called
    // We need to load the layer properties and update the selected layer in the dropdown
    element.addEventListener('cornerstoneactivelayerchanged', function(e) {
        const eventData = e.detail;
        const layer = cornerstone.getActiveLayer(element);
        const colormap = layer.viewport.colormap || '';
        const opacity = layer.options.opacity == null ? 1 : layer.options.opacity;

        // Restore all properties for the active layer
        document.getElementById('imageOpacity').value = opacity;
        document.querySelector("input[name=visible]").checked = layer.options.visible === undefined ? true : layer.options.visible;
        document.getElementById('colormaps').value = colormap;

        updateSelectedLayer(eventData.layerId);
    });


    // Populate colormap dropdown with all the default ones
    function fillColormapsList() {
        const dropdown = document.getElementById('colormaps');
        const colormapsList = cornerstone.colors.getColormapsList();

        const addOption = function(id, name) {
            const option = document.createElement("OPTION");
            option.value = id;
            option.textContent = name;

            dropdown.append(option);
        };

        colormapsList.forEach(function(colormapItem) {
            addOption(colormapItem.id, colormapItem.name);
        });
    }

      // add event handlers to pan image on mouse move
      element.addEventListener('mousedown', function (e) {
        let lastX = e.pageX;
        let lastY = e.pageY;
        const mouseButton = e.which;

        function mouseMoveHandler(e) {
          const deltaX = e.pageX - lastX;
          const deltaY = e.pageY - lastY;
          lastX = e.pageX;
          lastY = e.pageY;

          if (mouseButton === 1) {
            let viewport = cornerstone.getViewport(element);
            viewport.voi.windowWidth += (deltaX / viewport.scale);
            viewport.voi.windowCenter += (deltaY / viewport.scale);
            cornerstone.setViewport(element, viewport);
          } else if (mouseButton === 2) {
            let viewport = cornerstone.getViewport(element);
            viewport.translation.x += (deltaX / viewport.scale);
            viewport.translation.y += (deltaY / viewport.scale);
            cornerstone.setViewport(element, viewport);
          } else if (mouseButton === 3) {
            let viewport = cornerstone.getViewport(element);
            viewport.scale += (deltaY / 100);
            cornerstone.setViewport(element, viewport);

            document.getElementById('layerViewportScale').innerText = viewport.scale;
          }

          const layer1 = cornerstone.getLayers(element)[0];
          const layer2 = cornerstone.getLayers(element)[1];

          document.getElementById('layer1LayerViewportScale').innerText = layer1.viewport.scale;
          document.getElementById('layer2LayerViewportScale').innerText = layer2.viewport.scale;
          document.getElementById('layer1LayerSyncScale').innerText = layer1.syncProps.originalScale;
          document.getElementById('layer2LayerSyncScale').innerText = layer2.syncProps.originalScale;
          
        }

        function mouseUpHandler() {
          document.removeEventListener('mouseup', mouseUpHandler);
          document.removeEventListener('mousemove', mouseMoveHandler);
        }

        document.addEventListener('mousemove', mouseMoveHandler);
        document.addEventListener('mouseup', mouseUpHandler);
      });

      const mouseWheelEvents = ['mousewheel', 'DOMMouseScroll'];
      mouseWheelEvents.forEach(function(eventType) {
        element.addEventListener(eventType, function (e) {
          // Firefox e.detail > 0 scroll back, < 0 scroll forward
          // chrome/safari e.wheelDelta < 0 scroll back, > 0 scroll forward
          let viewport = cornerstone.getViewport(element);
          if (e.wheelDelta < 0 || e.detail > 0) {
            viewport.scale -= 0.25;
          } else {
            viewport.scale += 0.25;
          }

          cornerstone.setViewport(element, viewport);

          // Prevent page from scrolling
          return false;
        });
      });

    // Start point to load all layers and colormaps and
    // also attach a click listener to each tool
    loadLayers();
    fillColormapsList();
</script>
</html>
